import shutil
import os
import sys
from pathlib import Path
from tqdm import tqdm

from command_utils import get_current_time
from command_utils import data_96bytes_parser

"""
    file_utils.py

    @description:
        文件工具类
    @author:
        zhenyu
    @date:
        2024/6/6
"""


def get_parent_path():
    current_path = Path(__file__).resolve()
    # 主目录
    return current_path.parent.parent.parent


def empty_directory(path: str) -> bool:
    """
    清空给定路径下的文件夹，包括所有文件和子目录
    :param path: 需要被清空的目录路径
    :return:
    """
    # 验证路径的合法性，确保路径指向预期的目录，避免路径注入风险
    last_part = str(path).replace("//","\\").split("\\")[-1]

    if not os.path.isdir(path):
        print(f"路径 {path} 不是一个有效的目录。")
        return False
    try:
        for file in Path(path).glob("*"):
            if file.is_file():
                file.unlink()
            elif file.is_dir():
                shutil.rmtree(file)
        return True
    except Exception as e:
        print(f"empty_directory Exception: {e}")
        return False


def count_files_in_directory(directory_path: str):
    """
    计算指定目录下的文件数量
    :param directory_path: 要检查的目录路径,绝对路径
    :return: 目录中的文件数量
    """

    try:
        # 列出目录中的所有条目
        entries = os.scandir(directory_path)
        # 过滤出文件（排除子目录）
        files = [entry for entry in entries if entry.is_file()]
        # 返回文件数量
        return len(files)
    except OSError as e:
        print(f"Error accessing directory: {e}")
        return 0
    finally:
        entries.close()  # 确保scandir对象关闭


def empty_directory_list(path_list: list) -> bool:
    """
    清空给定列表路径下的文件夹，包括所有文件和子目录
    :param path_list: 需要被清空的目录路径列表
    :return:
    """

    if not path_list:
        print("path_list is empty")
        return False

    flag = False

    for path in tqdm(path_list, desc="Emptying directory: "):
        flag = empty_directory(path)

    return flag


def combine_96pkgs_data_txt(driver_type: str, index: int):
    """
    将rgb/thermal目录下的单独96字节的TXT文件合并为365所要求格式
    /mc 任务机保存的原始96字节文件信息

    :param driver_type: rgb/thermal/mc 设备类型
    :param index:   需要合并的文件数量
    :return:
    """
    # 获取文件
    folder = get_parent_path() / "data"
    data_file_type = ""

    if driver_type.lower() == "rgb":
        folder = folder / "rgb_fly_data"
        data_file_type = "rgb_fly_data"
    if driver_type.lower() == "thermal":
        folder = folder / "thermal_fly_data"
        data_file_type = "thermal_fly_data"
    if driver_type.lower() == "mc":
        folder = folder / "mc_origin_fly_data"
        data_file_type = "mc_origin_fly_data"

    # 将文件夹下的文件合并到z_submit_fly_data_time目录下
    # 并使用时间戳进行命名
    time_str = get_current_time().replace(" ", "-").replace(":", "_")
    # 新建文件
    new_combine_file = ""
    if driver_type.lower() == "rgb":
        new_combine_file = parent_path / "data" / "z_submit_fly_data_time" / (time_str + ".txt")
    if driver_type.lower() == "thermal":
        new_combine_file = parent_path / "data" / "z_submit_fly_data_time" / (time_str + "_all" + ".txt")
    if driver_type.lower() == "mc":
        new_combine_file = parent_path / "data" / "z_submit_fly_data_time" / (time_str + "_all_mc" + ".txt")

    if not new_combine_file.exists():
        new_combine_file.touch()

    with open(new_combine_file, "w", encoding="utf-8") as file:
        file.write(
            "序号,航向角,俯仰角,倾斜角,空速,气压高度,GPS地速,"
            "纬度,经度,GPS高度,航迹角,年,月,日,时,分,秒,"
            "起飞点海拔,无人机东向速度,无人机北向速度,无人机天向速度,"
            "拼接图像宽,拼接图像高,拼接图像坐标原点,目标数量,"
            "1号目标信息,1号左上X,1号左上Y,1号右下X,1号右下Y,"
            "2号目标信息,2号左上X,2号左上Y,2号右下X,2号右下Y,"
            "关联图片,摄像头序号,")

    # 关联图片索引存储文件从0开始，故设置为-1
    relate_image_index = -1
    current_second_value = 0
    for i in tqdm(range(index + 1), desc="Combining 96pkgs files: "):

        temp_dict = {}
        list_value = []
        temp_second_value = 0

        fly_data_file = folder / (data_file_type + "_" + str(i) + ".txt")

        if not fly_data_file.exists():
            continue

        with open(fly_data_file, "r", encoding="utf-8") as file:
            temp_dict["id"] = str(i)
            list_value.append(str(i))
            for line in file:
                if ':' in line:
                    parts = line.split(':')
                    left_value = parts[0].strip()
                    right_value = parts[1].strip()
                    # print(f"{left_value}:{right_value}")
                    list_value.append(right_value)
                    temp_dict[left_value] = right_value
                    # 通过是否在同一秒进行判断，是否需要增加图片索引
                    if left_value.lower() == "second":
                        # print(f"{left_value}:{right_value}")
                        temp_second_value = right_value

            if temp_second_value != current_second_value:
                relate_image_index = relate_image_index + 1
                current_second_value = temp_second_value

            temp_dict["relate_image"] = f"img/{driver_type}/frame_{relate_image_index}"
            list_value.append(f"img/{driver_type}/frame_{relate_image_index}")

        if len(list_value) > 0:
            with open(new_combine_file, "a", encoding="utf-8") as file:
                file.write("\n" + " ".join(list_value))

    print(f"{folder}目录下前{index}个文件合并到{new_combine_file}中")


def combine_96pkgs_data_mc_origin(absolute_file_path: str, file_counts):
    """
    将rgb/thermal目录下的单独96字节的TXT文件合并为365所要求格式

    :param absolute_file_path:  需要合并的文件路径
    :param file_counts:   需要合并的文件数量
    :return:
    """
    for i in tqdm(range(file_counts), desc="Saving MCM 96pkgs files: "):
        temp_data = []
        pkgs_96_file_path = absolute_file_path + "//file_" + str(i) + ".txt"
        with open(pkgs_96_file_path, "r", encoding="utf-8") as file:
            line = file.readline()
            temp_data = bytes.fromhex(line)

        if len(temp_data) > 0:
            data_96bytes_parser("MC", temp_data, i)

    combine_96pkgs_data_txt("MC", file_count)


if __name__ == '__main__':
    parent_path = get_parent_path()
    video_rgb_path = parent_path / "captureVideo" / "rgb"
    video_thermal_path = parent_path / "captureVideo" / "thermal"
    data_rgb_path = parent_path / "data" / "rgb_fly_data"
    data_thermal_path = parent_path / "data" / "thermal_fly_data"
    data_mc_origin_path = parent_path / "data" / "mc_origin_fly_data"
    data_submit_data_time = parent_path / "data" / "z_submit_fly_data_time"
    img_rgb_path = parent_path / "img" / "rgb"
    img_thermal_path = parent_path / "img" / "thermal"
    test_96pkgs_info_path = parent_path / "test" / "96pkgs_info"
    test_fly_data_path = parent_path / "test" / "fly_data"

    path_list = []
    path_list.append(str(video_rgb_path))
    path_list.append(str(video_thermal_path))
    path_list.append(str(data_rgb_path))
    path_list.append(str(data_thermal_path))
    path_list.append(str(data_mc_origin_path))
    path_list.append(str(img_rgb_path))
    path_list.append(str(img_thermal_path))
    path_list.append(str(test_96pkgs_info_path))
    path_list.append(str(test_fly_data_path))

    # 运行注意清空文件夹和合并文件只运行一个 zhen yu
    # 提供用户输入选择功能
    while True:
        user_input = input("请输入1清空文件夹，2合并文件，3合并所有96字节文件（暂时用thermal存放）,"
                           "4合并任务机中原始96字节文件, 5退出程序:")
        if user_input == "1":
            print("正在清空文件夹 ing")
            empty_directory_list(path_list)
            print("清空文件夹 success")
        elif user_input == "2":
            print("合并96字节文件")
            file_count = count_files_in_directory(str(data_rgb_path))
            print(f"需要合并{file_count}个文件")
            combine_96pkgs_data_txt("rgb", file_count)
            print("合并文件 success")
        elif user_input == "3":
            print("合并所有96字节文件")
            file_count = count_files_in_directory(str(data_thermal_path))
            print(f"需要合并{file_count}个文件")
            combine_96pkgs_data_txt("thermal", file_count)
            print("合并所有文件 success")
        elif user_input == "4":
            print("合并任务机96字节文件")
            file_path = input("请输入任务机原始96字节文件路径: ")
            absolute_mc_origin_path = file_path.replace("/", "//")
            file_count = count_files_in_directory(str(absolute_mc_origin_path))
            print(f"需要合并{file_count}个文件")
            combine_96pkgs_data_mc_origin(str(absolute_mc_origin_path), file_count)
            print("合并任务机96字节文件 success")
        elif user_input == "5":
            sys.exit()
